package com.ibm.iisp.common.dao;

import java.io.StringWriter;
import java.util.List;
import java.util.Map;

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.ibm.iisp.common.util.JacksonObjectMapperFactory;

/**
 * 
 * 转换通用的多属性字段到数据库单个VARCHAR字段
 * 
 * @author JohnnyZhou
 *
 */
@Converter
public class ObjectJsonConverter implements AttributeConverter<Object, String> {
	private static final String VAL_STR = "\"data\":";
	private static final String CLASS_ATR = "\"class\":\"";
	ObjectMapper objectMapper = JacksonObjectMapperFactory.getObjectMapper();

	@Override
	public String convertToDatabaseColumn(Object val) {
		if (val == null) {
			return null;
		}
		try {
			StringWriter sw = new StringWriter(4000);
			Class<?> clz = val.getClass();
			if (List.class.isAssignableFrom(clz)) {
				clz = List.class;
			} else if (Map.class.isAssignableFrom(clz)) {
				clz = Map.class;
			}
			sw.append("{").append(CLASS_ATR).append(clz.getName()).append("\",").append(VAL_STR);
			sw.append(objectMapper.writeValueAsString(val));
			sw.append("}");
			return sw.toString();
		} catch (Exception ex) {
			throw new RuntimeException("JSON 转换出错:" + val, ex);
		}
	}

	@Override
	public Object convertToEntityAttribute(String dbData) {
		if (dbData == null) {
			return null;
		}
		try {
			@SuppressWarnings("unchecked")
			Map<String, Object> _map = objectMapper.readValue(dbData, Map.class);
			Class<?> clz = Class.forName((String) _map.get("class"));
			Object dv = _map.get("data");
			String _data = objectMapper.writeValueAsString(dv);
			Object ov = objectMapper.readValue(_data, clz);
			return ov;
		} catch (Exception ex) {
			throw new RuntimeException("JSON 转换出错:" + dbData, ex);
		}
	}

}
